package org.gap.jseed.reflect;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class AbstractClassIterator {

	protected Collection<Class<?>> getClassHierarchy(Class<?> javaClass) {
		Map<String, Class<?>> result = new HashMap<String, Class<?>>();
		
		result.put(javaClass.getName(), javaClass);
		Class<?> currentClass = javaClass;
		while (hasSuperClass(currentClass)) {
			currentClass = getSuperClass(currentClass);
			result.put(currentClass.getName(), currentClass);
		}
		
		Map<String, Class<?>> interfaces = new HashMap<String, Class<?>>();
		for (Class<?> eachClass : result.values()) {
			for (Class<?> eachInterface : eachClass.getInterfaces()) {
				interfaces.put(eachInterface.getName(), eachInterface);
				ArrayList<Class<?>> extendsInterfaces = new ArrayList<Class<?>>();
				extendsInterfaces.add(eachInterface);
				while (!extendsInterfaces.isEmpty()) {
					Class<?> nextInterface = extendsInterfaces.remove(0);
					extendsInterfaces.addAll(Arrays.asList(nextInterface.getInterfaces()));
					interfaces.put(nextInterface.getName(), nextInterface);
				}
			}
		}
		for (String each : interfaces.keySet()) {
			result.put(each, interfaces.get(each));
		}
		
		result.remove(Object.class.getName());
		
		return result.values();
	}

	private boolean hasSuperClass(Class<?> childClass) {
		return childClass.getSuperclass() != null;
	}

	private Class<?> getSuperClass(Class<?> childClass) {
		return childClass.getSuperclass();
	}

}